#include "frame_thread_pool.h"

#include "users_login.h"
#include "deal_command.h"  // 包含 struct_userOpInfo struct_tlv

static void *threadFunc(void *arg) {
	threadPool_t *threadPool = (threadPool_t *)arg;

	while (1) {
		int netfd;

		pthread_mutex_lock(&threadPool->mutex);

		while (threadPool->taskQueue.size == 0 && threadPool->exitFlag == 0) {
			pthread_cond_wait(&threadPool->cond, &threadPool->mutex);
		}

		if (threadPool->exitFlag == 1) {
			printf("\nI am worker. I am going to exit!\n");
			// 子线程退出不用dequeue， 不用关netfd， 主线程帮着关了
			pthread_mutex_unlock(&threadPool->mutex);
			pthread_exit(NULL);
		}

		deQueue(&threadPool->taskQueue, &netfd);
		printf("\nI am worker, I got netfd = %d\n", netfd);

		pthread_mutex_unlock(&threadPool->mutex);

		printf("Next, do something!\n");
		printf("\n");


		// work

		// 登录 注册功能
		userOpInfo_t useropinfo;
		memset(&useropinfo, 0, sizeof(useropinfo));

		// 初始化useropinfo  mysql netfd addr
		// ID uesrName 在Login得到
		// opName 在recv得到
		useropinfo.mysql = threadPool->mysql;
		useropinfo.netfd = netfd;
		strcpy(useropinfo.addr, userSpace);

		int ret = 1;
		ret = usersLogin(&useropinfo);
		if (ret == -1) {
			printf("\n");
			pthread_exit(NULL);
		}

		printf("In thread: netfd = %d\n", useropinfo.netfd);
		printf("In thread: ID = %d\n", useropinfo.ID);
		printf("In thread: addr = %s\n", useropinfo.addr);
		printf("In thread: userName = %s\n", useropinfo.userName);
		printf("\n");

		// 处理客户端请求
		// 对每一个客户端输入的命令
		// 收客户端发来的命令
		// 然后根据命令tlv的t执行相应的操作
		// 最后将操作的结果返回给客户端
		tlvPacket_t tlv;
		memset(&tlv, 0, sizeof(tlv));

		while (1) {
			ret = recv(useropinfo.netfd, &tlv.type, sizeof(tlv.type), MSG_WAITALL);
			if (ret == 0) {
				break;
			}
			ret = recv(useropinfo.netfd, &tlv.length, sizeof(tlv.length), MSG_WAITALL);
			if (ret == 0) {
				break;
			}
			if (tlv.length != 0) {
				ret = recv(useropinfo.netfd, tlv.value, tlv.length, MSG_WAITALL);
				if (ret == 0) {
					break;
				}
				memset(useropinfo.opName, 0, sizeof(useropinfo.opName));
				strncpy(useropinfo.opName, tlv.value, sizeof(useropinfo.opName));
				useropinfo.opName[tlv.length] = '\0';
			}

			printf("command: %d,  file: %s\n", tlv.type, useropinfo.opName);

			ret = dealCommand(&useropinfo, &tlv);
			if (ret == -1) {
				printf("Error! waiting for next command\n\n");
				continue;
			}
			printf("\n");
		}

		close(netfd);

	}
}

int makeWorker(threadPool_t *threadPool) {
	for (int i = 0; i < threadPool->tidArr.workerNum; i++) {
		pthread_create(&threadPool->tidArr.arr[i], NULL, threadFunc, threadPool);
	}
	return 0;
}
